home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / support / ildr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-18  |  13.0 KB  |  712 lines

  1. /*    
  2.  *    ilwrite() : write driver
  3.  *        1. copy Lock request info to lockbuf
  4.  *        2. follow action in l_act
  5.  *        3. Error return conditions
  6.  *            -1: lockrequest fails(only on act=1)
  7.  *            -2: attempt to release a lock not set
  8.  *                by calling program
  9.  *            -3: illegal action requested
  10.  */
  11.  
  12. # include    <stdio.h>
  13. # include    <sys/param.h>
  14. # include    <sys/socket.h>
  15. # include    <netinet/in.h>
  16. # include    <sys/ioctl.h>
  17. # include    <errno.h>
  18. # include    <ildr.h>
  19. # include    <sys/time.h>
  20. # include    <netdb.h>
  21. # include    <signal.h>
  22.  
  23. # define    TRUE    1
  24. # define    FALSE    0
  25.  
  26. # ifdef    DEBUG
  27. static int ildebug = TRUE;
  28. # endif    DEBUG
  29.  
  30. int    From_server;        /* read connection from socket server */
  31. long    Read_fmt;        /* bit mask for select */
  32. char    *Prog_name;        /* program name for abnormal errors */
  33.  
  34. /*
  35. ** main
  36. ** initilize the socket to the socket server, and then sit and on
  37. ** a select waiting for input.
  38. */
  39. main(ac,av)
  40. int    ac;
  41. char    **av;
  42. {
  43.     long        read_fd,        /* bit mask of useable descriptors*/
  44.             num_des;        /* number of readable descriptors */
  45.     void        abnormal();        /* error function */
  46.     register    int    i;        /* index */
  47.  
  48.  
  49.     /*
  50.     ** close all the files descriptors, so we can have more INGRES
  51.     ** processes. We are lmited by file descriptors.
  52.     */
  53. # ifdef    DEBUG
  54.     setbuf(stdout,NULL);
  55.     printf("DRIVER: starting up\n");
  56.     for ( i = 3 ; i < NOFILE ; i++ )
  57. # else
  58.     for ( i = 1 ; i < NOFILE ; i++ )
  59. # endif    DEBUG
  60.         close(i);
  61.  
  62.     /*
  63.     ** set up all the signals. Catching any signal
  64.     ** is an error. We do a "warm start" in this condition
  65.     */
  66.     for ( i = 0 ; i < NSIG ; i++ )
  67.         signal(i,abnormal);
  68.     signal(SIGPIPE,SIG_IGN);    /* ignore this one, in case a process simply dies in mid stride */
  69.     Prog_name = *av;
  70.     /*
  71.     ** if ac == 2, then we are restarted from the the lock driver
  72.     ** itself, and we don't have to reattach ourselves to the magic
  73.     ** ingres socket.
  74.     */
  75.     if ( ac == 2 )
  76.         From_server = 0;
  77.     else {
  78.         /* guarantee that 0 is what is attached to the socket server */
  79.         close(0);
  80.         From_server = init_socket();
  81.     }
  82.     Read_fmt = (1<<From_server);
  83.  
  84.     /*
  85.     ** infinite loop waiting for something to happen
  86.     */
  87.     for ( ;; )
  88.     {
  89.         read_fd = Read_fmt;
  90.  
  91.         /*
  92.         ** wake up whenever something happens
  93.         */
  94.         while ( (num_des = select(NOFILE,&read_fd,0,0,0)) == 0 )
  95.         {
  96. # ifdef    DEBUG
  97.         printf("select returns 0 (%o)\n",read_fd);
  98. # endif    DEBUG
  99.             read_fd = Read_fmt;
  100.         }
  101. # ifdef    DEBUG
  102.         printf("select returns %d (%o)\n",num_des,read_fd);
  103. # endif    DEBUG
  104.         if ( num_des == -1 )
  105.         {
  106. # ifdef    DEBUG
  107.             perror("DRIVER:num_des = -1");
  108. # endif DEBUG
  109.             /*
  110.             ** a bit of defensive programming.
  111.             ** If there is an EBADF (bad file descriptor) error 
  112.             ** then we assume that a file descriptor has shut down,
  113.             ** with out tellng us. We go to a function to figure
  114.             ** out what has died.
  115.             */
  116.             if ( errno == EBADF )
  117.                 close_up(Read_fmt);
  118.             sleep(1);
  119.             continue;
  120.         }
  121.         if ( (read_fd & (1<<From_server)) )
  122.         {
  123.             num_des--;
  124.             new_proc();
  125.             read_fd &= ~(1<<From_server);
  126.         }
  127.         if ( num_des > 0 )
  128.         {
  129.             for ( i = 0 ; i < NOFILE ; i++ )
  130.                 if ( (read_fd & (1<<i)) )
  131.                     ilwrite(i);
  132.         }
  133.     }
  134. }/* main */
  135.  
  136. /*
  137. ** new_proc
  138. ** start up a new connection to an Ingres process
  139. */
  140. new_proc()
  141. {
  142.     register    int    fd;
  143.     int    to_ioctl = 1;
  144.     struct    sockaddr_in    addr;
  145.     auto        int    len;
  146.  
  147.     len = sizeof (addr);
  148.     if ( (fd = accept(From_server,(struct sockaddr *)&addr,&len)) != -1 )
  149.     {
  150.         Read_fmt |= (1<<fd);
  151. #if 0
  152.         ioctl(fd,FIONBIO,&to_ioctl);
  153. #endif
  154.     }
  155. # ifdef    DEBUG
  156.     else
  157.     {
  158.         perror("accept");
  159.         sleep(1);
  160.     }
  161.     printf("DRIVER: new file %d (%o)\n",fd,(1<<fd));
  162. # endif    DEBUG
  163. }/* new_proc */
  164.  
  165.  
  166.  
  167. ilwrite(read_desc)
  168. register    int    read_desc;
  169. {
  170.     struct Lockreq    lockbuf;
  171.     register int i;
  172.     register int blockflag;
  173.     extern    int    errno;
  174.  
  175.     errno = 0;
  176. # ifdef    DEBUG
  177.     printf("DRIVER: entering ilwrite, read_desc = %d\n",read_desc);
  178. # endif    DEBUG
  179.     if ( read(read_desc,(char *)&lockbuf, sizeof ( lockbuf)) != sizeof ( lockbuf ) )
  180.     {
  181. # ifdef    DEBUG
  182.         printf("Read error, errno = %d\n",errno);
  183. # endif    DEBUG
  184.         if ( errno == EWOULDBLOCK )
  185.             return;
  186.         if ( errno == ECONNRESET )
  187.         {
  188.             ilrma(read_desc,TRUE);
  189.             close(read_desc);
  190.             Read_fmt &= ~(1<<read_desc);
  191.             return;
  192.         }
  193.         send_info(read_desc,-5);
  194.         return;
  195.     }
  196.  
  197. # ifdef    DEBUG
  198.     if (ildebug)
  199.         printf("ildr: act %d, type %d, mode %d, read_desc %d\n",
  200.             lockbuf.lr_act, lockbuf.lr_type, lockbuf.lr_mod, read_desc);
  201. # endif    DEBUG
  202.     if (( lockbuf.lr_act < A_RLS1)
  203.     && ((lockbuf.lr_type < T_CS) || (lockbuf.lr_type > T_DB )
  204.        || (lockbuf.lr_mod < M_EXCL) || (lockbuf.lr_mod > M_SHARE )))
  205.     {
  206. # ifdef    DEBUG
  207.         printf("Illegal request\n");
  208. # endif    DEBUG
  209.         send_info(read_desc,-5);
  210.         return;
  211.     }
  212. /*
  213.  *        follow action from lock request
  214.  */
  215.     switch(lockbuf.lr_act)
  216.     {
  217.       case A_RTN:
  218. # ifdef    DEBUG
  219.         if ( ildebug )
  220.             printf("Driver: A_RTN\n");
  221. # endif    DEBUG
  222.  
  223.         /*
  224.         ** attempt to set lock.
  225.         ** error return if failure.
  226.         */
  227.         for ( i = 0; i <= lockbuf.lr_type; i++) 
  228.         {
  229.             if (Lockset[i] == 0) 
  230.             {
  231. # ifdef    DEBUG
  232.                 if (ildebug)
  233.                     printf("ildr: lock %d not available\n", i);
  234. # endif    DEBUG
  235.                 send_info(read_desc,-1);
  236.                 return;
  237.             }
  238.         }
  239.         if (ilunique(&lockbuf) >= 0) 
  240.         {
  241.             send_info(read_desc,-1);
  242.             return;
  243.         }
  244. # ifdef    DEBUG
  245.         if ( ildebug )
  246.             printf("Driver: lock assigned\n");
  247. # endif    DEBUG
  248.         ilenter(&lockbuf,read_desc);
  249.         break;
  250.  
  251.       case A_SLP:
  252. # ifdef    DEBUG
  253.         if ( ildebug )
  254.             printf("Driver: A_SLP\n");
  255. # endif    DEBUG
  256.         if ( set_lock(read_desc,lockbuf) == -1 )
  257.             return;
  258. # ifdef    DEBUG
  259.         if ( ildebug )
  260.             printf("Driver: got lock\n");
  261. # endif    DEBUG
  262.         break;
  263.       case A_RLS1:
  264.                 /* remove 1 lock */
  265. # ifdef    DEBUG
  266.         if ( ildebug )
  267.             printf("Driver: A_RLS1\n");
  268. # endif    DEBUG
  269.         if ((i = ilfind(&lockbuf,read_desc)) >= 0)
  270.         {
  271.             ilrm(i,read_desc);
  272.         }
  273.         else
  274.         {
  275.             send_info(read_desc,-2);
  276.             return;
  277.         }
  278. # ifdef    DEBUG
  279.         if ( ildebug )
  280.             printf("Driver: released\n");
  281. # endif    DEBUG
  282.         break;
  283.  
  284.       case A_RLSA:
  285.                 /* remove all locks for this process id*/
  286. # ifdef    DEBUG
  287.         if ( ildebug )
  288.             printf("Driver: A_RLSA\n");
  289. # endif    DEBUG
  290.         ilrma(read_desc,FALSE);
  291.         break;
  292.  
  293.       case A_ABT:        /* remove all locks */
  294. # ifdef    DEBUG
  295.         if ( ildebug )
  296.             printf("Driver: A_ABT\n");
  297. # endif    DEBUG
  298.         ilclose();
  299.         break;
  300.  
  301.       default :
  302. # ifdef    DEBUG
  303.         if ( ildebug )
  304.             printf("DRIVER: garbage\n");
  305. # endif    DEBUG
  306.         send_info(read_desc,-3);
  307.     }
  308.     send_info(read_desc,0);
  309. }
  310. /*
  311.  *    ilunique- check for match on key
  312.  *    
  313.  *    return index of Locktab if match found
  314.  *    else return -1
  315.  */
  316. static
  317. ilunique(ll)
  318. register struct Lockreq *ll;
  319. {
  320.     register int    k;
  321.     register struct Lockform    *p;
  322.     register struct Lockreq    *q;
  323.  
  324.     for (k = 0; k < NLOCKS; k++)
  325.     {
  326.         p = &Locktab[k];
  327.         if ((p->l_mod != M_EMTY)
  328.         && (ilcomp(p->l_key,ll->lr_key) == 0)
  329.         && (p->l_type == ll->lr_type)
  330.         && ( (p->l_mod == M_EXCL) || (ll->lr_mod == M_EXCL)) ) {
  331. # ifdef    DEBUG
  332.             if (ildebug) {
  333.                 register int i;
  334.  
  335.                 printf("ildr: lock ");
  336.                 for (i = 0; i < KEYSIZE; i++)
  337.                     printf("%c", ll->lr_key[i]);
  338.                 printf(" busy\n");
  339.             }
  340. # endif    DEBUG
  341.             return(k);
  342.         }
  343.     }
  344.     return(-1);
  345. }
  346.  
  347. static
  348. ilfind(ll,key)
  349. register struct Lockreq *ll;
  350. int    key;
  351. {
  352.     register int    k;
  353.     register struct Lockform    *p;
  354.     register struct Lockreq    *q;
  355.  
  356.     for (k = 0; k < NLOCKS; k++)
  357.     {
  358.         p = &Locktab[k];
  359.         if ((p->l_mod != M_EMTY)
  360.         && (ilcomp(p->l_key,ll->lr_key) == 0)
  361.         && (p->l_type == ll->lr_type)
  362.         && (p->l_pid == key))
  363.             return(k);
  364.     }
  365.     return(-1);
  366. }/* ilfind */
  367.  
  368. /*
  369.  *    remove the lth Lock
  370.  *        if the correct user is requesting the move.
  371.  */
  372. static
  373. ilrm(l,key,remove_all)
  374. int l;
  375. int    key;
  376. int    remove_all;
  377. {
  378.     register struct Lockform *a;
  379.     register    k;
  380.  
  381.  
  382.     a = &Locktab[l];
  383.     if (a->l_pid == key && a->l_mod != M_EMTY)
  384.     {
  385.         if ( !remove_all && a->l_type == T_DB )
  386.             return;
  387.         a->l_mod = M_EMTY;
  388.         a->l_pid = 0;
  389.         if (a->l_wflag == W_ON)
  390.         {
  391.             a->l_wflag = W_OFF;
  392.             wakeup(&Locktab[l]);
  393.         }
  394.         for (k = 0; k <= a->l_type; k++)
  395.         {
  396.             Lockset[k]++;
  397.             if (Lockset[k] == 1)
  398.                 wakeup(&Lockset[k]);
  399.         }
  400.     }
  401. }/* ilrm */
  402.  
  403. /*
  404.  *    ilrma releases all locks for a given process id(pd)
  405.  *    -- called from sys1.c$exit() code.
  406.  */
  407. ilrma(key,remove_all)
  408. int key;
  409. int    remove_all;
  410. {
  411.     register int    i;
  412.  
  413. # ifdef    DEBUG
  414.     printf("DRVIER: Removing all, key = %d\n",key);
  415. # endif    DEBUG
  416.     for ( i = 0; i < NLOCKS; i++ )
  417.         ilrm(i,key,remove_all);
  418. }
  419.  
  420. /*
  421.  *    enter Lockbuf in locktable
  422.  *    return position in Locktable
  423.  *    error return of -1
  424.  */
  425. static
  426. ilenter(ll,key)
  427. register struct Lockreq *ll;
  428. int key;
  429. {
  430.     int    k,l;
  431.     register char    *f,*t;
  432.     register struct Lockform    *p;
  433.  
  434.     for (k = 0; k < NLOCKS; k++)
  435.     {
  436.         p = &Locktab[k];
  437.         if (p->l_mod == M_EMTY)
  438.         {
  439.             p->l_pid = key;
  440.             p->l_type = ll->lr_type;
  441.             Locktab[k].l_mod = p->l_mod = ll->lr_mod;
  442.             f = ll->lr_key;
  443.             t = p->l_key;
  444.             for (l = 0; l < KEYSIZE; l++)
  445.                 *t++ = *f++;
  446.             for (l = 0; l <= ll->lr_type; l++)
  447.                 Lockset[l]--;
  448. # ifdef    DEBUG
  449.             if ( ildebug )
  450.                 printf("DRIVER: ilenter %d, mod %d, omod = %d\n",k,p->l_mod,Locktab[k].l_mod);
  451. # endif    DEBUG
  452.             return(k);
  453.         }
  454.     }
  455. # ifdef    DEBUG
  456.     if ( ildebug )
  457.         printf("DRIVER: ilenter -1\n");
  458. # endif    DEBUG
  459.     return (-1);
  460. }
  461.  
  462. /*
  463.  *    ilcomp- string compare
  464.  *          returns 0 if strings match
  465.  *        returns -1 otherwise
  466.  */
  467. static
  468. ilcomp(s1,s2)
  469. register char *s1,*s2;
  470. {
  471.     register int    k;
  472.  
  473.     for (k = 0; k < KEYSIZE; k++)
  474.         if ( *s1++ != *s2++)
  475. # ifdef    DEBUG
  476.         {
  477.             if ( ildebug )
  478.                 printf("DRIVER: ilcomp returning -1\n");
  479.             return ( -1 );
  480.         }
  481. # else    DEBUG
  482.             return (-1);
  483. # endif    DEBUG
  484.     return (0);
  485. }
  486.  
  487. /*
  488.  *    ilclose- releases all locks
  489.  */
  490. static
  491. ilclose()
  492. {
  493.     register int    k;
  494.     register caddr_t c;
  495. # ifdef    DEBUG
  496.     printf("DRIVER: entered close\n");
  497. # endif    DEBUG
  498.  
  499.     for (k = 0; k < NLOCKS; k++)
  500.         wakeup( &Locktab[k] );
  501.     for (k = 0; k < 4; k++)
  502.         wakeup( &Lockset[k]);
  503.     for (c = (caddr_t)&Locktab[0].l_pid; c < (caddr_t)&Locktab[NLOCKS];)
  504.         *c++ = 0;
  505.     Lockset[0] = NLOCKS;
  506.     Lockset[1] = PLOCKS;
  507.     Lockset[2] = RLOCKS;
  508.     Lockset[3] = DLOCKS;
  509. }/* ilclose */
  510.  
  511. /*
  512. ** set_lock
  513. ** attempt to set a lock. If we can't, block the process and
  514. ** return -1, if we can than set the lock and return 0.
  515. */
  516. set_lock(read_desc,lockbuf)
  517. register    int    read_desc;
  518. struct    Lockreq    lockbuf;
  519. {
  520.     register    int    blockflag;
  521.     register    int    i;
  522.  
  523.     /*
  524.     ** attempt to set lock.
  525.     ** sleep on blocking address if failure.
  526.     */
  527.  
  528.     do
  529.     {
  530.         do
  531.         {
  532.             blockflag = TRUE;
  533.             for ( i = 0; i <= lockbuf.lr_type; i++)
  534.                 if (Lockset[i] == 0)
  535.                 {
  536. # ifdef    DEBUG
  537.                     if (ildebug)
  538.                         printf("ildr: lock %d not available\n", i);
  539. # endif    DEBUG
  540.                     wait_on(read_desc,&Lockset[i],lockbuf);
  541.                     return(-1);
  542.                 }
  543.         } while (!blockflag);
  544.  
  545.         if (( i = ilunique(&lockbuf)) >= 0 )
  546.         {
  547.             blockflag = FALSE;
  548.             Locktab[i].l_wflag = W_ON;
  549.             wait_on(read_desc,&Locktab[i],lockbuf);
  550.             return(-1);
  551.         }
  552.     } while (!blockflag);
  553.     ilenter(&lockbuf,read_desc);
  554.     return ( 0 );
  555. }/* set_lock */
  556.  
  557. /*
  558. ** send_info
  559. ** Send the data down the socket. Don't do it if it would cause the driver
  560. ** to block.
  561. */
  562. send_info(fd,data)
  563. register    int    fd;
  564. int    data;
  565. {
  566.     auto    int    wdes = ( 1<<fd );
  567.     struct    timeval    time;
  568.  
  569.     errno = 0;
  570.     time.tv_sec = 10;
  571.     time.tv_usec = 0;
  572.  
  573.     if ( select(NOFILE,0,&wdes,0,&time) != 1 )
  574.     {
  575.         Read_fmt &= ~(1<<fd);
  576.         ilrma(fd,TRUE);
  577.         close(fd);
  578.     }
  579.     else
  580.         if ( write(fd,&data,sizeof (int)) != sizeof (int) )
  581.         {
  582.             if ( errno == 0 )
  583.                 return;
  584.             Read_fmt &= ~(1<<fd);
  585.             ilrma(fd,TRUE);
  586.             close(fd);
  587.         }
  588. }/* send_info */
  589.  
  590. struct    Wait {
  591.     int    wait_fd;        /* file descriptor to send lock info to off of */
  592.     int    wait_lock;        /* what lock we are waiting for */
  593.     struct    Lockreq    wait_req;    /* the lock request */
  594.     struct    Wait    *next;
  595. };
  596. struct    Wait    *Wait_queue = NULL;
  597.  
  598. /*
  599. ** wait_on
  600. ** Set up to wait for a free lock.
  601. */
  602. wait_on(fd,lock,req)
  603. register    int    fd, lock;
  604. struct        Lockreq    req;
  605. {
  606.     register    struct    Wait    *ptr;
  607.     char    *calloc();
  608.  
  609.     ptr = (struct Wait *)calloc(1,sizeof (struct Wait));
  610.     ptr->wait_fd = fd;
  611.     ptr->wait_lock = lock;
  612.     ptr->wait_req = req;
  613.     ptr->next = Wait_queue;
  614.     Wait_queue = ptr;
  615. }/* wait_on */
  616.  
  617. /*
  618. ** wakeup
  619. ** See if there is anythng waiting on the newly freed lock. If there is,
  620. ** tell it it can have the lock now.
  621. */
  622. wakeup(lock)
  623. register    int    lock;
  624. {
  625.     register    struct    Wait    *ptr,*back;
  626.  
  627.     for ( back = NULL, ptr = Wait_queue ; ptr != NULL ; back = ptr, ptr = ptr->next )
  628.     {
  629.         if ( ptr->wait_lock == lock )
  630.         {
  631.             if ( set_lock(ptr->wait_fd,ptr->wait_req) == 0 )
  632.             {
  633.                 send_info(ptr->wait_fd,0);
  634.                 if ( back != NULL )
  635.                     back->next = ptr->next;
  636.                 else
  637.                     Wait_queue = Wait_queue->next;
  638.                 free(ptr);
  639.                 return;
  640.             }
  641.         }
  642.     }
  643. }/* wakeup */
  644.  
  645. /*
  646. ** abnormal
  647. ** a signal has come down and hit us. We restart the entire
  648. ** program, and hope it goes away
  649. */
  650. abnormal(sig)
  651. int    sig;
  652. {
  653.     extern    int    errno;
  654.  
  655. # ifdef    DEBUG
  656.     printf("DRIVER: error %d, restarting\n",sig);
  657. # endif
  658.  
  659.     execl("/etc/lock_driver","lock_driver","restart",0);
  660.     execl(Prog_name,Prog_name,"restart",0);
  661.     execlp("lock_driver","lock_driver","restart",0);
  662.     exit(4);
  663. }/* abnormal */
  664.  
  665. /*
  666. ** close_up
  667. ** try and find a closed up file descriptor.
  668. */
  669. close_up(fmt)
  670. long    fmt;
  671. {
  672.     long    rdesc;
  673.     register    int    i;
  674.     struct    timeval    time;
  675.  
  676.     errno = 0;
  677.     time.tv_sec  = 0;
  678.     time.tv_usec = 0;
  679.  
  680.     for ( i = 0 ; i < NOFILE ; i++ )
  681.     {
  682.         if ( (1<<i) & fmt )
  683.         {
  684.             rdesc = (1<<i);
  685.             if ( select(NOFILE,&rdesc,0,0,&time) == -1 )
  686.             {
  687.                 /*
  688.                 ** the server socket has closed down.
  689.                 ** BOY ARE WE IN TROUBLE
  690.                 */
  691.                 if ( i == From_server )
  692.                 {
  693.                     sleep(1);
  694. # ifdef    DEBUG
  695.                     printf("Restarting socket\n");
  696. # endif    DEBUG
  697.                     init_socket();
  698.                 }
  699.                 if ( errno == EBADF )
  700.                 {
  701. #if 0
  702.                     shutdown(i,2);
  703. #endif
  704.                     close(i);
  705.                     Read_fmt &= ~(1<<i);
  706.                     ilrma(i,TRUE);
  707.                 }
  708.             }
  709.         }
  710.     }
  711. }/* close_up */
  712.